// websocket.service.ts 或 websocket.ts
import type { SocketMessageEvent } from 'ws';
interface SocketOptions {
  url: string;
  heartbeatInterval?: number;
  reconnectInterval?: number;
  maxReconnectAttempts?: number;
}
class WebSocketService {
  private socket: WebSocket | null = null;
  private reconnectAttempts: number = 0;
  constructor(private options: SocketOptions) {}
  private createSocket(): void {
    this.socket = new WebSocket(this.options.url);
    this.socket.addEventListener('open', this.handleOpen);
    this.socket.addEventListener('message', this.handleMessage);
    this.socket.addEventListener('close', this.handleClose);
    this.socket.addEventListener('error', this.handleError);
  }
  private handleOpen = (): void => {
    console.log('已建立 WebSocket 连接.');
    // 可选地发送hello消息或执行其他初始化任务
    this.reconnectAttempts = 0;
    if (this.options.heartbeatInterval) {
      this.setupHeartbeat();
    }
  };
  private handleMessage = (event: SocketMessageEvent): void => {
    const data = JSON.parse(event.data); // 消息是json编码的
    console.log('Received message 连接成功:', data);
    // 使用接收到的数据Dispatch事件或调用回调函数
  };
  private handleClose = (event: CloseEvent): void => {
    console.log('WebSocket connection closed:', event.reason);
    this.socket = null;
    this.scheduleReconnect();
  };
  private handleError = (event: Event): void => {
    console.log('WebSocket error:连接错误', event);
    this.socket?.close(); // Ensure the socket is closed in case of an error
    this.scheduleReconnect();
  };
  private setupHeartbeat(): void {
    const interval = setInterval(() => {
      if (this.socket && this.socket.readyState === WebSocket.OPEN) {
        this.socket.send(JSON.stringify({ type: 'ping' }));
      } else {
        clearInterval(interval);
      }
    }, this.options.heartbeatInterval!);
  }
  private scheduleReconnect(): void {
    if (
      this.options.maxReconnectAttempts !== undefined &&
      this.reconnectAttempts >= this.options.maxReconnectAttempts
    ) {
      console.log('已达到最大重新连接尝试次数。中止.');
      return;
    }
    const delay = this.options.reconnectInterval ?? 5000; // Default to 5 seconds
    console.log(`尝试重新连接n ${delay}ms...`);
    setTimeout(() => {
      this.reconnectAttempts++;
      this.createSocket();
    }, delay);
  }
  public connect(): void {
    if (!this.socket) {
      this.createSocket();
    }
  }
  public disconnect(): void {
    if (this.socket) {
      this.socket.close();
      this.socket = null;
    }
  }
  public send(data: any): void {
    if (this.socket && this.socket.readyState === WebSocket.OPEN) {
      this.socket.send(JSON.stringify(data));
    } else {
      console.warn('无法发送消息：WebSocket 未打开.');
    }
  }
}

export default WebSocketService;
